using System;
using System.Collections;
//
// DotNetNuke® - http://www.dotnetnuke.com
// Copyright (c) 2002-2010
// by DotNetNuke Corporation
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
//
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Xml;
using DotNetNuke.Entities.Portals;
using DotNetNuke.Framework.Providers;
using DotNetNuke.Services.Exceptions;
using DotNetNuke.Services.Localization;
using Telerik.Web.UI;
using DotNetNuke.UI.Utilities;
using DotNetNuke.Entities.Modules;
using DotNetNuke.UI;
using System.Collections.Generic;

namespace DotNetNuke.HtmlEditor.TelerikEditorProvider
{

    public class EditorProvider : DotNetNuke.Modules.HTMLEditorProvider.HtmlEditorProvider
    {
        private Panel withEventsField__panel = new Panel();

        #region "Private Members"

        private Panel _panel
        {
            get { return withEventsField__panel; }
            set
            {
                if (withEventsField__panel != null)
                {
                    withEventsField__panel.Init -= Panel_Init;
                    withEventsField__panel.Load -= Panel_Load;
                    withEventsField__panel.PreRender -= Panel_PreRender;
                }
                withEventsField__panel = value;
                if (withEventsField__panel != null)
                {
                    withEventsField__panel.Init += Panel_Init;
                    withEventsField__panel.Load += Panel_Load;
                    withEventsField__panel.PreRender += Panel_PreRender;
                }
            }
        }
        private RadEditor withEventsField__editor = new RadEditor();
        private RadEditor _editor
        {
            get { return withEventsField__editor; }
            set
            {
                if (withEventsField__editor != null)
                {
                    withEventsField__editor.Load -= RadEditor_Load;
                }
                withEventsField__editor = value;
                if (withEventsField__editor != null)
                {
                    withEventsField__editor.Load += RadEditor_Load;
                }
            }

        }
        //properties that will be skipped during ConfigFile processing

        private string _propertiesNotSupported = ",ContentProviderTypeName,ToolProviderID,Modules,AllowScripts,DialogHandlerUrl,RegisterWithScriptManager,ClientStateFieldID,Enabled,Visible,ControlStyleCreated,HasAttributes,ClientID,ID,EnableViewState,NamingContainer,BindingContainer,Page,TemplateControl,Parent,TemplateSourceDirectory,AppRelativeTemplateSourceDirectory,Site,UniqueID,Controls,ViewState,ViewStateIgnoreCase,";
        //default paths for the editor file browser dialogs (portal based)

        private System.String[] _portalRootPath = new string[] { FileSystemValidation.EndUserHomeDirectory };
        //config file settings
        private bool _isControlInitialized = false;

        private bool _languageSet = false;
        private const string ProviderType = "htmlEditor";
        private static ProviderConfiguration _providerConfiguration = ProviderConfiguration.GetProviderConfiguration(ProviderType);

        private DotNetNuke.Framework.Providers.Provider objProvider = (DotNetNuke.Framework.Providers.Provider)_providerConfiguration.Providers[_providerConfiguration.DefaultProvider];
        #endregion
        private Exception _TrackException = null;
        private List<string> customStyles = new List<string>();

        #region "Properties"

        private ArrayList _additionalToolbars;
        public override ArrayList AdditionalToolbars
        {
            get { return _additionalToolbars; }
            set { _additionalToolbars = value; }
        }

        public override string ControlID
        {
            get { return _editor.ID; }
            set { _editor.ID = value; }
        }

        public override Unit Height
        {
            get { return _editor.Height; }
            set
            {
                if ((!value.IsEmpty))
                {
                    _editor.Height = value;
                }
            }
        }

        public override Control HtmlEditorControl
        {
            get { return (Control)_panel; }
        }

        private string _rootImageDirectory = string.Empty;
        public override string RootImageDirectory
        {
            get
            {
                if ((string.IsNullOrEmpty(_rootImageDirectory)))
                {
                    return PortalSettings.HomeDirectory;
                }
                else
                {
                    return _rootImageDirectory;
                }
            }
            set { _rootImageDirectory = value; }
        }

        public override string Text
        {
            get { return _editor.Content; }
            set { _editor.Content = value; }
        }

        public override Unit Width
        {
            get { return _editor.Width; }
            set
            {
                if ((!value.IsEmpty))
                {
                    _editor.Width = value;
                }
            }
        }

        private string _toolsFile = string.Empty;
        public string ToolsFile
        {
            get
            {
                if ((string.IsNullOrEmpty(_toolsFile) && (objProvider.Attributes["ToolsFile"] != null)))
                {
                    _toolsFile = objProvider.Attributes["ToolsFile"];
                }

                return _toolsFile;
            }
            set
            {
                _editor.ToolsFile = value;
                _toolsFile = value;
            }
        }

        private string _configFile = string.Empty;
        public string ConfigFile
        {
            get
            {
                if ((string.IsNullOrEmpty(_configFile) && (objProvider.Attributes["ConfigFile"] != null)))
                {
                    _configFile = objProvider.Attributes["ConfigFile"];
                }

                return _configFile;
            }
            set
            {
                _configFile = value;
                if ((_isControlInitialized))
                {
                    ProcessConfigFile();
                }
            }
        }

        private bool _filterHostExtensions = true;
        public bool FilterHostExtensions
        {
            get { return _filterHostExtensions; }
            set { _filterHostExtensions = value; }
        }

        private string _providerPath = string.Empty;
        public string ProviderPath
        {
            get
            {
                if ((string.IsNullOrEmpty(_providerPath) && (objProvider.Attributes["providerPath"] != null)))
                {
                    _providerPath = objProvider.Attributes["providerPath"];
                }
                else
                {
                    _providerPath = "~/Providers/HtmlEditorProviders/Telerik/";
                }

                if ((!_providerPath.EndsWith("/")))
                {
                    _providerPath = _providerPath + "/";
                }

                return _providerPath;
            }
        }

        #endregion

        #region "Public Methods"

        public override void AddToolbar()
        {
        }

        public override void Initialize()
        {
            _panel.Init += new EventHandler(Panel_Init);
            _panel.Load += new EventHandler(Panel_Load);
            _panel.PreRender += new EventHandler(Panel_PreRender);
            _editor.Load += new EventHandler(RadEditor_Load);
            try
            {
                //initialize the control
                LoadEditorProperties();
                _isControlInitialized = true;
                _editor.EnableViewState = false;
                _editor.ExternalDialogsPath = ProviderPath + "Dialogs/";

                if ((!string.IsNullOrEmpty(ToolsFile)))
                {
                    if(GetValidConfigFile(ToolsFile) != null)
                    {
                        ToolsFile = GetFileValueVirtualPath(ToolsFile);
                        _editor.ToolsFile = ToolsFile;
                    }
                }

                ProcessConfigFile();
            }
            catch (Exception ex)
            {
                _TrackException = new Exception("Could not load RadEditor. " + Environment.NewLine + ex.Message, ex);
                Exceptions.LogException(_TrackException);
            }
        }

        protected void Panel_Init(object sender, EventArgs e)
        {
            try
            {
                if (((_TrackException == null)))
                {
                    AddCustomScript(_panel);

                    customStyles.Add(".reTool .SaveTemplate { background-image: url('" + _panel.Page.ResolveUrl(ProviderPath + "images/SaveTemplate.gif") + "'); }");

                    _editor.OnClientCommandExecuting = "OnClientCommandExecuting"; //this can be further extended we can hardcode all the client events here and reference them in the CustomFunctions.js file
                    
                    SetEmoticonsTool(false);
                    AddHtmlTemplates();
                    SetCustomStyles();
                    _editor.RegisterWithScriptManager = true;

                    _panel.Controls.Add(_editor);
                }
            }
            catch (Exception ex)
            {
                _TrackException = new Exception("Could not load RadEditor." + Environment.NewLine + ex.Message, ex);
                Exceptions.LogException(_TrackException);
            }
        }

        protected void Panel_Load(object sender, EventArgs e)
        {
            try
            {
                if (((_TrackException == null)))
                {
                    //register the override CSS file to take care of the DNN default skin problems
                    const string AlreadyLoadedKey = "TelerikEditorProvider-EditorOverrideLoaded";
                    bool alreadyLoaded = HttpContext.Current != null && HttpContext.Current.Items[AlreadyLoadedKey] != null;
                    if (alreadyLoaded)
                    {
                        return;
                    }

                    ScriptManager pageScriptManager = ScriptManager.GetCurrent(_panel.Page);
                    if (((pageScriptManager != null)) && (pageScriptManager.IsInAsyncPostBack))
                    {
                        AddCustomScript(_panel);
                    }
                    else if (_panel.Page.Header != null)
                    {
                        AddCustomScript(_panel.Page.Header);
                    }

                    HttpContext.Current.Items[AlreadyLoadedKey] = true;
                }
            }
            catch (Exception ex)
            {
                _TrackException = new Exception("Could not load RadEditor." + Environment.NewLine + ex.Message, ex);
                Exceptions.LogException(_TrackException);
            }
        }

        protected void Panel_PreRender(object sender, EventArgs e)
        {
            try
            {
                //Exceptions are causing a stream of other NullReferenceExceptions
                //as a work around, track the exception and print out
                if (((_TrackException != null)))
                {
                    _panel.Controls.Clear();
                    _panel.Controls.Add(new LiteralControl(_TrackException.Message));
                }

                //temporary fix to DNN-14206  
                if(_panel.Parent is DotNetNuke.UI.WebControls.DNNRichTextEditControl)
                {
                    _editor.OnClientCommandExecuting = "";
                    SetEmoticonsTool(true);
                }

                PortalModuleBase parentModule = ControlUtilities.FindParentControl<PortalModuleBase>(HtmlEditorControl);
                int moduleid = Convert.ToInt32(parentModule == null ? -1 : parentModule.ModuleId);
                int portalId = Convert.ToInt32(parentModule == null ? -1 : parentModule.PortalId);
                int tabId = Convert.ToInt32(parentModule == null ? -1 : parentModule.TabId);
                ClientAPI.RegisterClientVariable(HtmlEditorControl.Page, "editorModuleId", moduleid.ToString(), true);
                ClientAPI.RegisterClientVariable(HtmlEditorControl.Page, "editorTabId", tabId.ToString(), true);
                ClientAPI.RegisterClientVariable(HtmlEditorControl.Page, "editorPortalId", portalId.ToString(), true);
                ClientAPI.RegisterClientVariable(HtmlEditorControl.Page, "editorHomeDirectory", PortalSettings.HomeDirectory, true);
                ClientAPI.RegisterClientVariable(HtmlEditorControl.Page, "editorPortalGuid", PortalSettings.GUID.ToString(), true);
                ClientAPI.RegisterClientVariable(HtmlEditorControl.Page, "editorEnableUrlLanguage", PortalSettings.EnableUrlLanguage.ToString(), true);

            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        protected void RadEditor_Load(object sender, EventArgs e)
        {
            try
            {
                if (((_TrackException == null)))
                {
                    SetLanguage();

                    //set content paths to portal root
                    SetContentPaths(_editor.ImageManager);
                    SetContentPaths(_editor.FlashManager);
                    SetContentPaths(_editor.MediaManager);
                    SetContentPaths(_editor.DocumentManager);
                    SetContentPaths(_editor.SilverlightManager);
                    SetContentPaths(_editor.TemplateManager);

                    //set content provider type
                    Type providerType = typeof(PortalContentProvider);
                    string providerName = providerType.FullName + ", " + providerType.Assembly.FullName;
                    _editor.ImageManager.ContentProviderTypeName = providerName;
                    _editor.DocumentManager.ContentProviderTypeName = providerName;
                    _editor.FlashManager.ContentProviderTypeName = providerName;
                    _editor.MediaManager.ContentProviderTypeName = providerName;
                    _editor.SilverlightManager.ContentProviderTypeName = providerName;
                    _editor.TemplateManager.ContentProviderTypeName = providerName;

                    //SetSearchPatterns
                    //telerik defaults + dnn extensions filter
                    string patterns = string.Empty;
                    patterns = "*.gif, *.xbm, *.xpm, *.png, *.ief, *.jpg, *.jpe, *.jpeg, *.tiff, *.tif, *.rgb, *.g3f, *.xwd, *.pict, *.ppm, *.pgm, *.pbm, *.pnm, *.bmp, *.ras, *.pcd, *.cgm, *.mil, *.cal, *.fif, *.dsf, *.cmx, *.wi, *.dwg, *.dxf, *.svf".Replace(", ", ",");
                    SetFileManagerSearchPatterns(_editor.ImageManager, patterns);
                    patterns = ("*.doc, *.txt, *.docx, *.xls, *.xlsx, *.pdf" + ", *.ppt, *.pptx, *.xml, *.zip").Replace(", ", ",");
                    SetFileManagerSearchPatterns(_editor.DocumentManager, patterns);
                    patterns = "*.swf".Replace(", ", ",");
                    SetFileManagerSearchPatterns(_editor.FlashManager, patterns);
                    patterns = "*.wma, *.wmv, *.avi, *.wav, *.mpeg, *.mpg, *.mpe, *.mp3, *.m3u, *.mid, *.midi, *.snd, *.mkv".Replace(", ", ",");
                    SetFileManagerSearchPatterns(_editor.MediaManager, patterns);
                    patterns = "*.xap".Replace(", ", ",");
                    SetFileManagerSearchPatterns(_editor.SilverlightManager, patterns);
                    patterns = "*.htmtemplate, *.htm, *,html".Replace(", ", ",");
                    SetFileManagerSearchPatterns(_editor.TemplateManager, patterns);

                    //Can't set individual dialogdefinitions because they are not available, instead set globally for all dialogs
                    //this is done to fix problem with TemplateManager Window not reloading after saving a template
                    _editor.DialogOpener.Window.ReloadOnShow = true;

                    //Set dialog handlers
					string tempHandlerUrl = "Telerik.Web.UI.DialogHandler.aspx?tabid=" + PortalSettings.ActiveTab.TabID.ToString() + "&language=" + PortalController.GetCurrentPortalSettings().CultureCode;
                    _editor.DialogHandlerUrl = _panel.Page.ResolveUrl(ProviderPath + tempHandlerUrl);
                    tempHandlerUrl = "Telerik.Web.UI.SpellCheckHandler.ashx?tabid=" + PortalSettings.ActiveTab.TabID.ToString();
                    _editor.SpellCheckSettings.AjaxUrl = _panel.Page.ResolveUrl(ProviderPath + tempHandlerUrl);
                }
            }
            catch (Exception ex)
            {
                _TrackException = new Exception("Could not load RadEditor." + Environment.NewLine + ex.Message, ex);
                Exceptions.LogException(_TrackException);
            }
        }

        #endregion

        #region "Config File related code"

        private string GetFilePath(string path, string fileDescription)
        {
            string convertedPath = path;
            if (convertedPath.StartsWith("~") || convertedPath.StartsWith("~"))
            {
                convertedPath = _panel.ResolveUrl(path);
            }

            convertedPath = Context.Request.MapPath(convertedPath);
            if (!File.Exists(convertedPath))
            {
                throw new Exception("Invalid " + fileDescription + ". Check provider settings in the web.config: " + path);
            }

            return convertedPath;
        }

        private XmlDocument GetValidConfigFile(string filePath)
        {
            XmlDocument xmlConfigFile = new XmlDocument();
            try
            {
                string mappedPath = Context.Request.MapPath(GetFileValueVirtualPath(filePath));

                if (!File.Exists(mappedPath))
                {
                    string fileName = Path.GetFileName(mappedPath);
                    string filePathFromProvider = Context.Request.MapPath(ProviderPath + "Config/" + fileName);

                    if (File.Exists(filePathFromProvider))
                    {
                        File.Copy(filePathFromProvider, mappedPath);
                    }
                }

                xmlConfigFile.Load(mappedPath);

            }
            catch (Exception generatedExceptionName)
            {
                throw new Exception("Invalid Configuration File:" + filePath);
            }
            return xmlConfigFile;
        }

        //don't allow property assignment of certain base control properties
        private void ProcessConfigFile()
        {
            if (ConfigFile != string.Empty)
            {
                XmlDocument xmlDoc = GetValidConfigFile(ConfigFile);
                foreach (XmlNode node in xmlDoc.DocumentElement.ChildNodes)
                {
                    if (node.Attributes == null || node.Attributes["name"] == null)
                    {
                        continue;
                    }

                    string propertyName = node.Attributes["name"].Value;
                    string propValue = node.InnerText;

                    if ((propertyName.ToLower() == "cssfiles"))
                    {
                        AddCssFiles(propValue);
                        continue;
                    }

                    //don't allow property assignment of certain base control properties
                    if ((_propertiesNotSupported.Contains("," + propertyName + ",")))
                    {
                        throw new NotSupportedException("Property assignment is not supported [" + propertyName + "]");
                    }

                    //use reflection to set all string, integer, long, short, bool, enum properties
                    SetEditorProperty(_editor, propertyName, propValue);
                }
            }
        }

        private void SetEditorProperty(object source, string propName, string propValue)
        {
            string[] properties = propName.Split('.');

            if ((properties.Length > 0))
            {
                for (int i = 0; i <= properties.Length - 2; i++)
                {
                    if ((_propertiesNotSupported.Contains("," + properties[i] + ",")))
                    {
                        throw new NotSupportedException("Property assignment is not supported for this property FullPath:[" + propName + "] Property:[" + properties[i] + "]");
                    }

                    PropertyInfo prop = source.GetType().GetProperty(properties[i]);
                    if ((prop == null))
                    {
                        throw new NotSupportedException("Property does not exist. FullPath:[" + propName + "] Property:[" + properties[i] + "]");
                    }

                    source = prop.GetValue(source, null);
                    if ((source == null))
                    {
                        throw new NotSupportedException("Property does not exist or is null. FullPath:[" + propName + "] Property:[" + properties[i] + "]");
                    }
                }
                SetProperty(source, properties[properties.Length - 1], propValue);
            }
        }

        private void SetProperty(object source, string propName, string propValue)
        {
            try
            {
                if ((source == null))
                {
                    return;
                }
                //Dim pi As PropertyInfo = DotNetNuke.Common.Utilities.DataCache.GetCache(Of PropertyInfo)("Telerik.EditorProvider." + propName + ".InfoCache")
                //If (pi Is Nothing) Then
                //	pi = _editor.GetType().GetProperty(propName)
                //	DotNetNuke.Common.Utilities.DataCache.SetCache("Telerik.EditorProvider." + propName + ".InfoCache", pi)
                //End If

                propValue = GetFileValueVirtualPath(propValue);

                PropertyInfo pi = source.GetType().GetProperty(propName);
                object propObj = null;
                if ((pi != null))
                {
                    if (pi.PropertyType.Equals(typeof(string)))
                    {
                        pi.SetValue(source, propValue, null);
                    }
                    else if (pi.PropertyType.Equals(typeof(bool)))
                    {
                        pi.SetValue(source, bool.Parse(propValue), null);
                    }
                    else if (pi.PropertyType.Equals(typeof(Unit)))
                    {
                        pi.SetValue(source, Unit.Parse(propValue), null);
                    }
                    else if (pi.PropertyType.Equals(typeof(int)))
                    {
                        pi.SetValue(source, int.Parse(propValue), null);
                    }
                    else if (pi.PropertyType.Equals(typeof(short)))
                    {
                        pi.SetValue(source, short.Parse(propValue), null);
                    }
                    else if (pi.PropertyType.Equals(typeof(long)))
                    {
                        pi.SetValue(source, long.Parse(propValue), null);
                    }
                    else if (pi.PropertyType.BaseType.Equals(typeof(System.Enum)))
                    {
                        pi.SetValue(source, System.Enum.Parse(pi.PropertyType, propValue), null);
                    }
                    else if (pi.PropertyType.Equals(typeof(string[])))
                    {
                        pi.SetValue(source, propValue.Split(','), null);
                    }
                    else if (pi.PropertyType.Equals(typeof(Telerik.Web.UI.EditorFontCollection)))
                    {
                        propObj = pi.GetValue(source, null);
                        if (((propObj != null)))
                        {
                            ((Telerik.Web.UI.EditorFontCollection)propObj).Add(propValue);
                        }
                    }
                    else if (pi.PropertyType.Equals(typeof(Telerik.Web.UI.EditorFontSizeCollection)))
                    {
                        propObj = pi.GetValue(source, null);
                        if (((propObj != null)))
                        {
                            ((Telerik.Web.UI.EditorFontSizeCollection)propObj).Add(propValue);
                        }
                    }
                    else if (pi.PropertyType.Equals(typeof(Telerik.Web.UI.EditorRealFontSizeCollection)))
                    {
                        propObj = pi.GetValue(source, null);
                        if (((propObj != null)))
                        {
                            ((Telerik.Web.UI.EditorRealFontSizeCollection)propObj).Add(propValue);
                        }
                    }
                    else if (pi.PropertyType.Equals(typeof(Telerik.Web.UI.EditorSymbolCollection)))
                    {
                        propObj = pi.GetValue(source, null);
                        if (((propObj != null)))
                        {
                            ((Telerik.Web.UI.EditorSymbolCollection)propObj).Add(propValue);
                        }
                    }
                    else if (pi.PropertyType.Equals(typeof(Telerik.Web.UI.EditorColorCollection)))
                    {
                        propObj = pi.GetValue(source, null);
                        if (((propObj != null)))
                        {
                            ((Telerik.Web.UI.EditorColorCollection)propObj).Add(propValue);
                        }
                    }
                    else if (pi.PropertyType.Equals(typeof(Telerik.Web.UI.EditorParagraphCollection)))
                    {
                        propObj = pi.GetValue(source, null);
                        if (((propObj != null)))
                        {
                            ((Telerik.Web.UI.EditorParagraphCollection)propObj).Add(propValue, "." + propValue);
                        }
                    }
                }
                if ((propName == "Language"))
                {
                    _languageSet = true;
                }
            }
            catch (Exception ex)
            {
                throw new Exception("Error parsing config file Type:[" + source.GetType().ToString() + "] Property:[" + propName + "] Error:[" + ex.Message + "]", ex);
            }
        }

        private void AddCssFiles(string cssFiles)
        {
            string[] files = cssFiles.Split(',');

            if (files.Length > 0)
            {
                _editor.CssFiles.Clear();
                string cssfile = null;
                foreach (string cssfile_loopVariable in files)
                {
                    cssfile = cssfile_loopVariable;
                    cssfile = GetFileValueVirtualPath(cssfile);
                    _editor.CssFiles.Add(cssfile);
                }
            }
        }

        private string GetFileValueVirtualPath(string propValue)
        {
            if ((propValue.StartsWith("[PortalRoot]") || propValue.StartsWith("[ProviderPath]") || propValue.StartsWith("~")))
            {
                propValue = propValue.Replace("[PortalRoot]", PortalSettings.HomeDirectory);
                propValue = propValue.Replace("[ProviderPath]", ProviderPath);
                if ((propValue.StartsWith("~")))
                {
                    propValue = _panel.ResolveUrl(propValue);
                }
            }

            return propValue;
        }

        #endregion

        #region "Private Helper Methods"

        private void SetLanguage()
        {
            _editor.LocalizationPath = ProviderPath + "App_LocalResources/";

            if ((!_languageSet))
            {
                _editor.Language = PortalSettings.CultureCode;
            }

            if ((!ResourceFilesExist(_editor.LocalizationPath, _editor.Language)))
            {
                _editor.Language = Localization.SystemLocale;
            }

        }

        private EditorToolGroup FindToolGroup(ref object tool, string toolName)
        {
            EditorToolGroup group = null;
            foreach (EditorToolGroup editorTool in _editor.Tools)
            {
                tool = editorTool.FindTool(toolName);
                if ((tool) == null)
                {
                    continue;
                }
                else
                {
                    group = editorTool;
                    break;
                }
            }

            return group;
        }

        /// <summary>
        /// Adds the emoticons tool button to the html toolbar
        /// </summary>
        private void SetEmoticonsTool(bool remove)
        {
            if ((_editor.Tools.Count < 1))
                return;

            object emoticonsTool = null;
            EditorToolGroup emoticonsToolGroup = FindToolGroup(ref emoticonsTool, "Emoticons");

            if ((emoticonsTool) == null)
                return;

            if (!(emoticonsTool is EditorSplitButton))
                return;

            // temp fix to DNN-14206  
            if (remove)
            {
                object saveTemplateTool = null;
                EditorToolGroup saveTemplateToolGroup = FindToolGroup(ref saveTemplateTool, "SaveTemplate");

                if ((saveTemplateTool != null))
                {
                    saveTemplateToolGroup.Tools.Remove(saveTemplateTool as EditorTool);
                }

                emoticonsToolGroup.Tools.Remove(emoticonsTool as EditorTool);
                // remove emoticons
                return;
            }


            EditorSplitButton sp = emoticonsTool as EditorSplitButton;
            sp.Text = "Emoticons";


            string filePath = HttpContext.Current.Server.MapPath(ProviderPath) + "images\\Emoticons";
            string virtualPath = _panel.Page.ResolveUrl(ProviderPath + "images/Emoticons/");
            string[] extensions = new string[] {
		                                        "*.jpg",
		                                        "*.png",
		                                        "*.gif"
	                                           };

            if ((!Directory.Exists(filePath)))
                return;

            DirectoryInfo dir = new DirectoryInfo(filePath);
            List<FileInfo> dirFiles = null;

            dirFiles = GetFilesByExtension(dir, extensions);

            customStyles.Add("span.Emoticons { background-image: url('" + virtualPath + dirFiles[0].Name + "'); }");

            foreach (FileInfo dirFile in dirFiles)
            {
                string fname = dirFile.Name;
                sp.Items.Add("<img src='" + virtualPath + dirFile.Name + "' title='" + fname.Replace(dirFile.Extension, "") + "' />", virtualPath + dirFile.Name);
            }

        }

        /// <summary>
        /// Adds the HTML default templates to the template folder in the current portal
        /// </summary>

        private void AddHtmlTemplates()
        {
            string defaultPath = HttpContext.Current.Server.MapPath(ProviderPath) + "templates";
            string portalPath = PortalSettings.HomeDirectoryMapPath + "Templates";
            string[] extensions = new string[] {
		                                        "*.htm",
		                                        "*.htmtemplate",
		                                        "*.html",
		                                        "*.css"
	                                           };

            EnsurePortalFiles(portalPath, defaultPath, extensions);

        }

        /// <summary>
        /// Ensures that the portal has the default files from the provider folder and copies them if they're not present.
        /// </summary>
        /// <param name="portalPath">The portal path.</param>
        /// <param name="defaultPath">The providerdefault path.</param>
        /// <param name="extensions">The extensions.</param>
        /// <returns></returns>
        private bool EnsurePortalFiles(string portalPath, string defaultPath, string[] extensions)
        {
            DirectoryInfo dir = default(DirectoryInfo);
            List<FileInfo> dirFiles = new List<FileInfo>();

            //first check if the portal has the files
            if ((!Directory.Exists(portalPath)))
            {
                if ((!Directory.Exists(defaultPath)))
                {
                    return false;
                    // no emoticons available even in providers folder so exit
                }
                else
                {
                    if ((!CopyFilesToPortal(defaultPath, portalPath, extensions)))
                        return false;
                    // try copying the files to current portal
                }
            }
            else
            {
                //try get existing files from the providers folder
                dir = new DirectoryInfo(portalPath);
                dirFiles = GetFilesByExtension(dir, extensions);

                //if no files then try copying from providers folder
                if ((dirFiles.Count < 1))
                {
                    if ((!CopyFilesToPortal(defaultPath, portalPath, extensions)))
                        return false;
                }
            }

            return true;

        }

        /// <summary>
        /// Copies default files from provider folder to portal folder.
        /// </summary>
        /// <param name="defaultPath">The provider default path.</param>
        /// <param name="portalPath">The portal path.</param>
        /// <param name="extensions">The extensions.</param>
        /// <returns></returns>
        private bool CopyFilesToPortal(string defaultPath, string portalPath, string[] extensions)
        {
            if ((!Directory.Exists(defaultPath)))
                return false;

            DirectoryInfo dir = new DirectoryInfo(defaultPath);
            List<FileInfo> dirFiles = null;

            dirFiles = GetFilesByExtension(dir, extensions);

            if ((dirFiles.Count < 1))
                return false;
            // no files available so exit

            //copy all files to portal's folder
            DirectoryInfo portalDir = (Directory.Exists(portalPath) ? new DirectoryInfo(portalPath) : Directory.CreateDirectory(portalPath));

            foreach (FileInfo finfo in dirFiles)
            {
                File.Copy(finfo.FullName, portalDir.FullName + "\\" + finfo.Name);
            }

            return true;
        }

        /// <summary>
        /// Gets a list of files by extension.
        /// </summary>
        /// <param name="directory">The direcotory to look in</param>
        /// <param name="extensions">The extensions.</param>
        /// <returns></returns>
        private List<FileInfo> GetFilesByExtension(DirectoryInfo directory, string[] extensions)
        {
            List<FileInfo> dirFiles = new List<FileInfo>();
            foreach (string extension in extensions)
            {
                List<FileInfo> innerList = new List<FileInfo>();
                innerList = directory.GetFiles(extension, SearchOption.TopDirectoryOnly).ToList();
                foreach (FileInfo fi in innerList)
                {
                    string fileName = fi.FullName;
                    if ((!dirFiles.Exists((FileInfo f) => f.FullName == fileName)))
                    {
                        dirFiles.Add(fi);
                    }
                }
            }

            return dirFiles;
        }

        /// <summary>
        /// Adds additional css styles to the editor that are required by tools such as emoticons, templatemanager etc.
        /// </summary>
        private void SetCustomStyles()
        {
            StringBuilder styleTag = new StringBuilder();
            styleTag.Append("<style type=\"text/css\">");

            foreach (string style in customStyles)
            {
                styleTag.Append(style);
            }

            styleTag.Append("</style>");

            _panel.Controls.Add(new LiteralControl(styleTag.ToString()));
        }

        private void AddCustomScript(Control ctrl)
        {
            LiteralControl dialogRegister = new LiteralControl("<script type=\"text/javascript\" src=\"" + _panel.Page.ResolveUrl(ProviderPath + "js/RegisterDialogs.js") + "\"></script>");
            LiteralControl customFunctions = new LiteralControl("<script type=\"text/javascript\" src=\"" + _panel.Page.ResolveUrl(ProviderPath + "js/CustomFunctions.js") + "\"></script>");
            LiteralControl templateDialog = new LiteralControl("<script type=\"text/javascript\">var __textEditorSaveTemplateDialog = \"" + _panel.Page.ResolveUrl(ProviderPath + "Dialogs/SaveTemplate.aspx") + "\";</script>");

            HtmlLink cssOverrideLink = new HtmlLink();
            cssOverrideLink.Href = _panel.Page.ResolveUrl(ProviderPath + "EditorOverride.css");
            cssOverrideLink.Attributes.Add("type", "text/css");
            cssOverrideLink.Attributes.Add("rel", "stylesheet");
            cssOverrideLink.Attributes.Add("class", "Telerik_stylesheet");

            if (!ctrl.Controls.Contains(dialogRegister))
            {
                ctrl.Controls.Add(dialogRegister);
            }

            ctrl.Controls.Add(customFunctions);
            ctrl.Controls.Add(templateDialog);
            ctrl.Controls.Add(cssOverrideLink);
        }

        /// <summary>
        /// Check if resources files exist for the language specified.
        /// </summary>
        /// <param name="path">The path.</param>
        /// <param name="language">The language.</param>
        /// <returns></returns>
        private bool ResourceFilesExist(string path, string language)
        {
            DirectoryInfo dir = new DirectoryInfo(HttpContext.Current.Server.MapPath(path));
            FileInfo[] resFiles = dir.GetFiles("*.resx", SearchOption.TopDirectoryOnly);

            bool result = false;

            foreach (FileInfo resFile in resFiles)
            {
                string name = resFile.Name;
                if (name.Substring(name.IndexOf(".resx") - language.Length, language.Length) == language)
                {
                    result = true;
                }

                if (!result)
                    break;
            }
            return result;
        }

        private void SetContentPaths(FileManagerDialogConfiguration manager)
        {
            if (((manager.ViewPaths == null) || manager.ViewPaths.Length < 1))
            {
                manager.ViewPaths = _portalRootPath;
            }
            if (((manager.UploadPaths == null) || manager.UploadPaths.Length < 1))
            {
                manager.UploadPaths = _portalRootPath;
            }
            if (((manager.DeletePaths == null) || manager.DeletePaths.Length < 1))
            {
                manager.DeletePaths = _portalRootPath;
            }
        }

        private void SetFileManagerSearchPatterns(Telerik.Web.UI.FileManagerDialogConfiguration dialogConfig, string patterns)
        {
            if (((dialogConfig.SearchPatterns == null) || dialogConfig.SearchPatterns.Length < 1))
            {
                dialogConfig.SearchPatterns = ApplySearchPatternFilter(patterns.Split(','));
            }
            else
            {
                dialogConfig.SearchPatterns = ApplySearchPatternFilter(dialogConfig.SearchPatterns);
            }
        }

        private void RemoveTool(string sToolName)
        {
            EditorToolGroup toolbar = null;
            foreach (EditorToolGroup toolbar_loopVariable in _editor.Tools)
            {
                toolbar = toolbar_loopVariable;
                EditorTool toolRef = toolbar.FindTool(sToolName);
                if ((toolRef != null))
                {
                    toolbar.Tools.Remove(toolRef);
                }
            }
        }

        private void LoadEditorProperties()
        {
            try
            {
                if ((objProvider.Attributes["ConfigFile"] != null))
                    _configFile = objProvider.Attributes["ConfigFile"];
                if ((objProvider.Attributes["ToolsFile"] != null))
                    _toolsFile = objProvider.Attributes["ToolsFile"];
            }
            catch (Exception exc)
            {
                throw new Exception("Could not load RadEditor! Error while loading provider attributes: " + exc.Message);
            }
        }

        private string[] ApplySearchPatternFilter(string[] patterns)
        {
            if ((!FilterHostExtensions))
            {
                return patterns;
            }

            ArrayList returnPatterns = new ArrayList();
            string hostExtensions = DotNetNuke.Entities.Host.Host.FileExtensions.ToLowerInvariant().Replace(" ", "");

            if ((patterns.Length == 1 && patterns[0] == "*.*"))
            {
                //Include all host partterns
                foreach (string pattern in hostExtensions.Split(','))
                {
                    returnPatterns.Add("*." + pattern);
                }
            }
            else
            {
                foreach (string pattern in patterns)
                {
                    string p = pattern.Replace("*.", "").ToLowerInvariant();
                    if ((("," + hostExtensions + ",").IndexOf("," + p + ",") > -1))
                    {
                        returnPatterns.Add("*." + p);
                    }
                }
            }

            return (string[])returnPatterns.ToArray(typeof(string));
        }

        #endregion

    }

}
